package com.jl.slick.util.graphics;

import java.awt.event.*;
import java.awt.image.ImageObserver;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import org.lwjgl.opengl.GLContext;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Game;
import org.newdawn.slick.GameContainer;
//import org.newdawn.slick.Graphics;
//import org.newdawn.slick.Image;
import java.awt.Image;
import java.awt.Graphics;
import java.awt.Point;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import javax.swing.*;

public class TileSelector extends JFrame implements MouseListener, MouseMotionListener, KeyListener
{

	private static final long serialVersionUID = 1L;

	private SpriteSheet tileset;

	private String filename;
	private int filewidth, fileheight, tilewidth, tileheight, maxtilewidth, maxtileheight, tilegroupx, tilegroupy;
	private Image image;
	private BackgroundEditor editor;
	private boolean mouseDragged;
	private ArrayList<Point> tilestopaint;

	
	public TileSelector(String filename)
	{
		this.mouseDragged = false;
		this.filename = filename; //gets the filename and/or location
	//	CreateMenu(this); //generates menu
		try 
		{
			File rawimage = new File(filename); //creates a new file from the image file on the system
			image = ImageIO.read(rawimage); //attempts to import the file into an Image(awt) object
			JLabel img = new JLabel(new ImageIcon(image));
			this.setContentPane(img);
			img.addMouseListener(this); //adds mouse listener to image(Jlabel) itself, so that pixels are measured relative to it and not the frame
			img.addMouseMotionListener(this);
			editor = new BackgroundEditor(filename);
		} 
		catch (Exception e1) 
		{
			System.err.println("TS: Error creating image from given file. Incorrect file name or format? see stack trace: ");
			e1.printStackTrace();
		}
		this.tilewidth = -1; 
		this.tileheight = -1;
		this.filewidth = this.image.getWidth(this);
		this.fileheight = this.image.getHeight(this);
		this.addKeyListener(this);
		this.setSize(this.filewidth, fileheight); //+<value> is offset to account for jframe edging size. Rendered EXACTLY to spec, so content pane is slightly squeezed
		this.tilestopaint = new ArrayList<Point>(10);
	}
	
	
	private static void CreateMenu(TileSelector ts)
	{
		//Where the GUI is created:
		JMenuBar menuBar;
		JMenu menu;
		JMenuItem menuItem;

		//Create the menu bar.
		menuBar = new JMenuBar();

		//Build the first menu.
		menu = new JMenu("File");
		menu.setMnemonic(KeyEvent.VK_A);

		menuBar.add(menu);

		//a group of JMenuItems
		menuItem = new JMenuItem("Open...",
		                         KeyEvent.VK_T);
		menuItem.setAccelerator(KeyStroke.getKeyStroke(
		        KeyEvent.VK_1, ActionEvent.ALT_MASK));
		
		menu.add(menuItem);
		ts.setJMenuBar(menuBar);
	}
	
	
	public void setTileSize(int x, int y)
	{
		try
		{
			if(this.filewidth%x ==0 && this.fileheight%y == 0)
			{
				this.tilewidth = x;
				this.tileheight = y;
				editor.setTileSize(x, y);
			}
			else
				throw new SlickException ("Invalid tile size. Must be divisor of spritesheet size");
		}
		catch (SlickException e)
		{
			e.printStackTrace();
		}
		
	}
	
	//Calculates possible tile sizes based on the sprite sheet used.
	//returns a two dimensional array list, index 0 is an ArrayList of the possible
	// x values, and index 1 is an ArrayList of the possible y values.
	public List<List<Integer>> tileSize()
	{
		List<List<Integer>> returnval = new ArrayList<List<Integer>>(2);
		returnval.add(0, new ArrayList<Integer>(5));
		returnval.add(1, new ArrayList<Integer>(5));
		int i;
		for(i = 2; i<this.filewidth; i+=2)
		{
			if(this.fileheight%i == 0)
			returnval.get(0).add(i);
		}
	
		for(i = 2; i<this.fileheight; i+=2)
		{
			if(this.fileheight%i == 0)
				returnval.get(1).add(i);		
		}
		
		return returnval;
	}
	
	public void start() throws SlickException
	{
		if(this.tilewidth != -1 && this.tileheight != -1)
		{
			this.setVisible(true); 
			AppGameContainer test = new AppGameContainer(editor); //creates the constant render window. THE PAINTING SCREEN
			test.setDisplayMode(this.filewidth, this.fileheight, false);//sets the display for the painting screen.
			test.start();

		}
		else
			throw new SlickException ("Must initialize tile size first");

	}


	@Override
	public void mouseClicked(MouseEvent e)
	{	
		
	}


	@Override
	public void mouseEntered(MouseEvent e) {
		
	}


	@Override
	public void mouseExited(MouseEvent e) {

		
	}


	@Override
	public void mousePressed(MouseEvent e) {

		System.out.println(e.getPoint().x);
		System.out.println(e.getPoint().y);
		
	}


	@Override
	public void mouseReleased(MouseEvent e) 
	{
		this.tilestopaint.clear();
		if(this.mouseDragged)
		{
		System.out.println(e.getPoint().x);
		System.out.println(e.getPoint().y);
		}
		else
		{
			System.out.println("In else");
			/*lets the editor know which tile should be painted from the spritesheet. 
			 * The mouse clicked event returns values in terms of pixels, so must be divided
			 * by the tile size:  
			 * this may yield a decimal value, hence the int cast (which truncates the decimal
			 * points, which is needed. NO rounding!)
			 * the minus 1 is there to ensure that even in cases where the user selects
			 * the very edge of a given tile, it will still end up in selecting that one
			 * instead of the next over.
			 */
			tilestopaint.add(new Point((int)((e.getX()-1)/this.tilewidth), (int)((e.getY()-1)/this.tileheight)));
			editor.tilepaint((int)((e.getX()-1)/this.tilewidth), (int)((e.getY()-1)/this.tileheight));	
		}
		this.mouseDragged = false;
	}


	@Override
	public void keyPressed(KeyEvent e) {

		
	}


	@Override
	public void keyReleased(KeyEvent e) {

		
	}


	@Override
	public void keyTyped(KeyEvent e) {
	
		
	}


	@Override
	public void mouseDragged(MouseEvent e) 
	{
		this.mouseDragged= true;
	}


	@Override
	public void mouseMoved(MouseEvent e) {

	}





	

}//class end
